

/* all regular expressions */
var dateReg   = /(\d{1,2})\/(\d{1,2})\/(\d{4})\s+(\d{2}):(\d{2})/i;
//var coordsReg = /\s\(((\d+)\|(\d+))\)(\sK)?/i;
var coordsReg = /(\d+)\|(\d+)/i;


var host = window.location.host;
var vi = game_data.village.id;

var rallyLink = "http://" + host + "/game.php?village=" + vi + "&screen=place";

var url = window.location.href;
var id;
var config = null;
var opData = null;
var modules = null;

function getCurrentOP() {
	if(opData.currentOP) {
		var op = opData.opList[opData.currentOP];

		if(op) {
			$.each(modules, function(index, module) {
				module.initData(op);
			});
		}
		
		return op;
	}
}

function leadFormat(n) {
	if(n < 10) {
		return "0" + n;
	}
	return n;
}

function dateFormat(t) {
	var d = new Date(t);
	return leadFormat(d.getDate()) + "/" + leadFormat(d.getMonth() + 1) + "/" + d.getFullYear() + " " + leadFormat(d.getHours()) + ":" + leadFormat(d.getMinutes());
}

function dateParse(t) {
	var dateParts = dateReg.exec(t);
	if(dateParts && dateParts.length > 1) {
		var date = new Date(parseInt(dateParts[3]), parseInt(dateParts[2]) - 1, parseInt(dateParts[1]), parseInt(dateParts[4]), parseInt(dateParts[5]), 0);
		return date.getTime();
	}
	return 0;
}

/*
 * Config
 * */
function ConfigModule() {
	this.initData = function(obj) {
		if(obj.name == undefined) obj.name = "";
		if(obj.villages == undefined) obj.villages = new Array();
		if(obj.landingTime == undefined) obj.landingTime = 0;
	};
	
	this.redirect = function() {
		return false;
	};
	
	this.display = function(rootPane) {
		rootPane.append("Change OP settings");
		$.each(modules, function(index, module) {
			rootPane.append($("<h3>").append(index));
			module.displaySettings(rootPane);
		});
	};
	
	this.displaySettings = function(rootPane) {
		var table = $("<table>", {style:"border: solid 1px black"});
		
		var opRow = $("<tr>");
		opRow.append($("<td>").append("OP:"));
		
		var selCell = $("<td>");
		var select = $("<select>", {id:"selectOP"});
		select.append($("<option>", {value:-2,selected:"selected"}).append("--Select--"));
		for(var name in opData.opList) {
			var o = {value:name};
			if(name == opData.currentOP) {
				o.selected = "selected";
			}
			select.append($("<option>", o).append(name));
		}
		select.append($("<option>", {value:-1}).append("--New--"));
		selCell.append(select);
		opRow.append(selCell);
		
		table.append(opRow);
		rootPane.append(table);
		
		
		if(getCurrentOP() != null) {
			var landingRow = $("<tr>");
			landingRow.append($("<td>").append("Landing Time:"));
			landingRow.append($("<td>").append($("<input>", {id:"opTime", type:"text", value:dateFormat(getCurrentOP().landingTime)})));
			table.append(landingRow);
			
			
			var coordsRow = $("<tr>");
			coordsRow.append($("<td>").append("Coordinates:"));
			coordsRow.append($("<td>").append($("<textarea>", {id:"opVillages"}).append(getCurrentOP().villages.join(" "))));
			table.append(coordsRow);
		}
		
		var t = this;
		$("#selectOP").change(function() { t.selectOP($(this)); });
		$("#opTime").change(function() { t.changeOPTime($(this)); });
		$("#opVillages").change(function() { t.changeOPVillages($(this)); });
	};
	
	this.perform = function() {
	};
	
	this.changeOPVillages = function(select) {
		var coords = select.attr('value');
		var lines = coords.split(/\s+/);
		var res = new Array();
		for(var i = 0; i < lines.length; i++) {
			if(coordsReg.test(lines[i])) {
				res.push(lines[i]);
			}
		}
		getCurrentOP().villages = res;
		saveOPData();
		$("#opVillages").val(res.join(" "));
	};
	
	this.changeOPTime = function(select) {
		var time = select.val();
		var val = dateParse(time);
		if(val > 0) {
			getCurrentOP().landingTime = val;
			saveOPData();
		}
	};
	
	this.selectOP = function(input) {
		var op = input.val();
		if(op == -2) {
			return;
		}
		if(op != -1) {
			opData.currentOP = op;
			saveOPData();
			repaintModule();
		} else {
			this.addOP();
		}
	};
	
	this.addOP = function() {
		var res = prompt("Please enter the name of the new OP", "");
		if(!res || res.lenght == 0) {
			return;
		}
		
		if(!opData.opList[res]) {
			var obj = {};
			opData.opList[res] = obj;
			$.each(modules, function(index, module) {
				module.initData(obj);
			});
			obj.name = res;
		}
		opData.currentOP = res;
		
		saveOPData();
		repaintModule();
	};
	
	
	return this;
}

/*
 * Fakes
 */

function FakesModule() {
	this.initData = function(obj) {
		if(obj.lastIndex == undefined) obj.lastIndex = 0;
		if(obj.mode == undefined) obj.mode = "index";
		if(obj.tabCount == undefined) obj.tabCount = 0;
		if(obj.units == undefined) obj.units = {spy:'o', ram:'o', cat:'o'};
		if(obj.unitcounts == undefined) obj.unitcounts = {spy:1, ram:1, catapult:1};
	};
	
	this.redirect = function() {
		if(url.indexOf('screen=place') == -1) {
			window.location = rallyLink;
			return true;
		}
	};
	
	this.display = function(rootPane) {
		if(!getCurrentOP()) {
			rootPane.append($("<h3>").append("Select an OP first"));
			rootPane.append($("<input>", {type:"button", id:"configButton", value:"Select an OP first"}));
			$("#configButton").click(function() {module = "config"; main();});
			return;
		}
		
		rootPane.append($("<h2>").append("Send fakes for OP " + getCurrentOP().name));
		rootPane.append($("<h3>").append("Landing time: " + dateFormat(getCurrentOP().landingTime)));
		var currentTime = new Date().getTime();
		if(getCurrentOP().landingTime < currentTime) {
			rootPane.append($("<h3>", {style:"color: red;"}).append("Landing time has passed!"));
		}

		rootPane.append($("<h3>", {id:"errorLine", style:"color: red"}).toggle(false));
		
		var maxUnits = this.getUnitCounts();
		
		if(getCurrentOP().tabCount == 0) {
			if(getCurrentOP().mode == 'random') {
				rootPane.append("Send fake " + getCurrentOP().lastIndex + " of " + getCurrentOP().villages.length);
			} else {
				rootPane.append("Send random fake");
			}
			
			var res = this.setUnits($("body"), maxUnits);
			if(res !== true) {
				$("#errorLine").toggle(true).append("Problem: " + res);
			}
		} else {
			if(getCurrentOP().mode == 'random') {
				rootPane.append("Send fakes " + getCurrentOP().lastIndex + " to " + Math.min(getCurrentOP().tabCount + getCurrentOP().lastIndex, getCurrentOP().villages.length) + " of " + getCurrentOP().villages.length);
			} else {
				rootPane.append("Send " + getCurrentOP().tabCount + " random fakes");
			}
			
			rootPane.append($("<input>", {type:"button", id:"tabsButton", value:"Open tabs"}));
		}

		var t = this;
		$("#tabsButton").click(function() { t.openTabs(maxUnits); });
	};
	
	this.displaySettings = function(rootPane) {
		if(getCurrentOP() == null) {
			return;
		}
		var table = $("<table>", {style:"border: solid 1px black"});
		
		var modeRow = $("<tr>");
		modeRow.append($("<td>").append("Mode:"));
		
		var selCell = $("<td>");
		var select = $("<select>", {id:"selectFakeMode"});
		$.each(["index", "random"], function(index, mode) {
			var o = {value:mode};
			if(mode == getCurrentOP().mode) {
				o.selected = "selected";
			}
			select.append($("<option>", o).append(mode));
		});
		selCell.append(select);
		modeRow.append(selCell);
		
		table.append(modeRow);

		
		var tabCountRow = $("<tr>");
		tabCountRow.append($("<td>").append("Tab Count:"));
		var c = {id:"fakeTabCount", type:"text", value:getCurrentOP().tabCount};
		var o = {id:"fakeTabOn", type:"checkbox"};
		if(getCurrentOP().tabCount==0) {
			c.disabled = "true";
		} else {
			o.checked = "checked";
		}
		tabCountRow.append($("<td>")
				.append($("<input>", o))
				.append($("<input>", c)));
		table.append(tabCountRow);
		
		
		
		var unitTable = $("<table>");
		var headerRow = $("<tr>");
		headerRow.append($("<td>").append("Unit"));
		headerRow.append($("<td>").append("Exclude"));
		headerRow.append($("<td>").append("Optional"));
		headerRow.append($("<td>").append("Required"));
		headerRow.append($("<td>").append("Amount"));
		unitTable.append(headerRow);
		
		$.each(config.units, function(index, unit) {
			if(index == "list" || index == "snob" || index == "militia") {
				return;
			}
			
			var u1 = {class:"selectFakeUnit", name:index, type:"radio", value:""};
			var u2 = {class:"selectFakeUnit", name:index, type:"radio", value:"o"};
			var u3 = {class:"selectFakeUnit", name:index, type:"radio", value:"r"};
			
			var v = getCurrentOP().units[index];
			if(v == "o") {
				u2.checked = "checked";
			} else if(v == "r") {
				u3.checked = "checked";
			} else {
				u1.checked = "checked";
			}
			
			var unitRow = $("<tr>");
			unitRow.append($("<td>").append(index + ":"));
			unitRow.append($("<td>").append($("<input>", u1)));
			unitRow.append($("<td>").append($("<input>", u2)));
			unitRow.append($("<td>").append($("<input>", u3)));
			unitRow.append($("<td>").append($("<input>", {class:"countFakeUnit", type:"text", name:index, value:getCurrentOP().unitcounts[index]})));
			unitTable.append(unitRow);
		});
		
		
		var unitsRow = $("<tr>");
		unitsRow.append($("<td>").append("Units:"));
		unitsRow.append($("<td>").append(unitTable));
		table.append(unitsRow);
		
		
		
		rootPane.append(table);
		
		var t = this;
		$("#selectFakeMode").change(function() { t.selectMode($(this)); });
		$("#fakeTabCount").change(function() { t.editTabCount($(this)); });
		$("#fakeTabOn").change(function() { t.useTabCount($(this)); });
		$(".selectFakeUnit").change(function() { t.selectUnit($(this)); });
		$(".countFakeUnit").change(function() { t.selectUnitCount($(this)); });
	};
	
	this.selectUnit = function(input) {
		var mode = input.val();
		var name = input.attr("name");
		getCurrentOP().units[name] = mode;
		saveOPData();
	};
	
	this.selectUnitCount = function(input) {
		var amount = input.val();
		var name = input.attr("name");
		getCurrentOP().unitcounts[name] = amount;
		saveOPData();
	};
	
	this.selectMode = function(input) {
		var mode = input.val();
		getCurrentOP().mode = mode;
		saveOPData();
	};
	
	this.editTabCount = function(input) {
		getCurrentOP().tabCount = input.val();
		if(getCurrentOP().tabCount == 0) {
			$("#fakeTabCount").attr("disabled", "disabled");
			$("#fakeTabOn").removeAttr('checked');
		} else {
			$("#fakeTabCount").removeAttr("disabled");
			$("#fakeTabOn").attr('checked', 'checked');
		}
		saveOPData();
	};
	
	this.useTabCount = function(input) {
		var tab = input.attr('checked');
		getCurrentOP().tabCount = tab=='checked'?1:0;
		$("#fakeTabCount").val(getCurrentOP().tabCount);
		if(getCurrentOP().tabCount == 0) {
			$("#fakeTabCount").attr("disabled", "disabled");
		} else {
			$("#fakeTabCount").removeAttr("disabled");
		}
		saveOPData();
	};
	
	this.getUnitCounts = function() {
		var maxUnits = {};
		$.each(getCurrentOP().units, function(index, unit) {
			if(unit == "o" || unit == "r") {
				maxUnits[index] = eval($("#unit_input_" + index).next().html());
			}
		});
		return maxUnits;
	};
	
	this.setUnits = function(rootElement, maxUnits) {
		var index = getCurrentOP().lastIndex;
		
		if(getCurrentOP().mode == 'random') {
			index = Math.floor(Math.random() * getCurrentOP().villages.length);
		}
		
		if(index < 0) {
			index = 0;
		}
		if(index >= getCurrentOP().villages.length) {
			getCurrentOP().lastIndex = 0;
			saveOPData();
			return "All villages done";
		}
		
		
		var target = getCurrentOP().villages[index];
		
		var spycount = maxUnits["spy"];
		var spyrequirement = getCurrentOP().units["spy"];
		if(spyrequirement == 'r' && spycount < getCurrentOP().unitcounts["spy"]) {
			return "The scout is required, but you ran out of them.";
		}
		
		var unitAdded = false;
		
		for(var i = config.units.list.length - 1; i >= 0; i--) {
			var unit = config.units.list[i];
			if(unit.id == "snob" || unit.id == "militia" || unit.id == "spy") {
				continue;
			}
			var count = maxUnits[unit.id];
			if(count == undefined) { count = 0; }
			var requirement = getCurrentOP().units[unit.id];
			if(requirement == undefined) { requirement = ""; }

			if(requirement != 'r' && (count < getCurrentOP().unitcounts[unit.id] || requirement != 'o')) {
				continue;
			}
			if(requirement == 'r' && count < getCurrentOP().unitcounts[unit.id]) {
				return "The unit " + unit.id + " is required, but you ran out of them.";
			}
			maxUnits[unit.id] -= getCurrentOP().unitcounts[unit.id];
			$('#unit_input_' + unit.id, rootElement).val(getCurrentOP().unitcounts[unit.id]);
			unitAdded = true;
		}
		if(spyrequirement == 'r' || spyrequirement == 'o' && spycount >= getCurrentOP().unitcounts["spy"]) {
			maxUnits["spy"] -= getCurrentOP().unitcounts["spy"];
			$("#unit_input_spy", rootElement).val(getCurrentOP().unitcounts["spy"]);
			unitAdded = true;
		}
		if(unitAdded) {
			var c = target.split("|");
			$("#units_form input[name=x]", rootElement).val(c[0]);
			$("#units_form input[name=y]", rootElement).val(c[1]);
			getCurrentOP().lastIndex = index + 1;
			saveOPData();
			return true;
		} else {
			return "No units where added.";
		}
	};
	
	this.openTabs = function(maxUnits) {
		var t = this;
		var opener = {originwindow:window, index:0, target:null, fakesMod:t, maxUnits:maxUnits, timer:-1};
		
		this.loadWindow(opener);
	};
	
	this.loadWindow = function(opener) {
		if(opener.index >= getCurrentOP().tabCount) {
			return;
		}
		opener.index++;
		
		opener.target = opener.originwindow.open(rallyLink,'_blank');
		opener.timer = setInterval(function(){
			//
			if(opener.target.document.readyState === "complete" && $("#units_form input[name=x]", opener.target.document.body).length > 0) {
				clearInterval(opener.timer);
				var res = opener.fakesMod.setUnits(opener.target.document.body, opener.maxUnits);
				if(res !== true) {
					$("#errorLine", opener.originwindow.document.body).toggle(true).append("Problem: " + res);
					return;
				}
				opener.fakesMod.loadWindow(opener);
			} else {
				//just wait
			}
		}, 300);
		opener.originwindow.focus();
	};
}


/*
 * Nukes
 */

function NukesModule() {
	this.initData = function(obj) {
		if(obj.tabNukes == undefined) obj.tabNukes = true;
		if(obj.addScouts == undefined) obj.addScouts = 1;
		if(obj.unitsToInclude == undefined) obj.unitsToInclude = {axe:true, light:true, ram:true, catapult:true};
		if(obj.unitsToKeep == undefined) obj.unitsToKeep = {ram:20, catapult:20};
	};
	
	this.redirect = function() {
		if(url.indexOf('screen=place') == -1) {
			window.location = rallyLink;
			return true;
		}
	};
	
	this.display = function(rootPane) {
		if(!getCurrentOP()) {
			rootPane.append($("<h3>").append("Select an OP first"));
			rootPane.append($("<input>", {type:"button", id:"configButton", value:"Select an OP first"}));
			$("#configButton").click(function() {module = "config"; main();});
			return;
		}
		
		rootPane.append($("<h2>").append("Send nukes for OP " + getCurrentOP().name));
		rootPane.append($("<h3>").append("Landing time: " + dateFormat(getCurrentOP().landingTime)));
		var currentTime = new Date().getTime();
		if(getCurrentOP().landingTime < currentTime) {
			rootPane.append($("<h3>", {style:"color: red;"}).append("Landing time has passed!"));
		}
		
		var maxUnits = this.getUnitCounts();

		var time = this.getTravelTime(maxUnits);
		
		
		if(currentTime + time > getCurrentOP().landingTime) {
			rootPane.append($("<h3>", {style:"color: red;"}).append("Your nuke will land after the landing time: " + dateFormat(currentTime + time)));
		}

		rootPane.append($("<h3>", {id:"errorLine", style:"color: red"}).toggle(false));
		/*
		if(getCurrentOP().tabCount == 0) {
			if(getCurrentOP().mode == 'random') {
				rootPane.append("Send fake " + getCurrentOP().lastIndex + " of " + getCurrentOP().villages.length);
			} else {
				rootPane.append("Send random fake");
			}
			
			var res = this.setUnits($("body"), maxUnits);
			if(res !== true) {
				$("#errorLine").toggle(true).append("Problem: " + res);
			}
		} else {
			if(getCurrentOP().mode == 'random') {
				rootPane.append("Send fakes " + getCurrentOP().lastIndex + " to " + Math.min(getCurrentOP().tabCount + getCurrentOP().lastIndex, getCurrentOP().villages.length) + " of " + getCurrentOP().villages.length);
			} else {
				rootPane.append("Send " + getCurrentOP().tabCount + " random fakes");
			}
			
			rootPane.append($("<input>", {type:"button", id:"tabsButton", value:"Open tabs"}));
		}
*/
		var t = this;
		$("#tabsButton").click(function() { t.openTabs(maxUnits); });
	};
	
	this.displaySettings = function(rootPane) {
		if(getCurrentOP() == null) {
			return;
		}
		var table = $("<table>", {style:"border: solid 1px black"});
		rootPane.append(table);
		
		var tabRow = $("<tr>");
		tabRow.append($("<td>").append("Open in new tab:"));
		var o = {id:"nukeTab", type:"checkbox"};
		if(getCurrentOP().tabNukes) {
			o.checked = "checked";
		}
		tabRow.append($("<td>").append($("<input>", o)));
		table.append(tabRow);

		
		var unitTable = $("<table>");
		var headerRow = $("<tr>");
		headerRow.append($("<td>").append("Unit"));
		headerRow.append($("<td>").append("Include"));
		headerRow.append($("<td>").append("Leave behind"));
		unitTable.append(headerRow);
		
		$.each(config.units, function(index, unit) {
			if(index == "list" || index == "snob" || index == "militia") {
				return;
			}

			var o = {class:"unitToInclude", type:"checkbox", name:index};
			
			if(getCurrentOP().unitsToInclude[index]) {
				o.checked = "checked";
			}

			
			if(index == "spy") {
				o = {id:"addScoutCount", type:"text", value:getCurrentOP().addScouts};
			}
			
			var unitRow = $("<tr>");
			unitRow.append($("<td>").append(index + ":"));
			unitRow.append($("<td>").append($("<input>", o)));
			unitRow.append($("<td>").append($("<input>", {class:"unitToKeep", type:"text", name:index, value:getCurrentOP().unitsToKeep[index]})));

			unitTable.append(unitRow);
		});
		
		
		var unitsRow = $("<tr>");
		unitsRow.append($("<td>", {colspan:2}).append(unitTable));
		table.append(unitsRow);
		
		
		var t = this;
		$("#nukeTab").change(function() { t.useTab($(this)); });
		$("#addScoutCount").change(function() { t.editScoutCount($(this)); });
		$(".unitToInclude").change(function() { t.selectUnitToInclude($(this)); });
		$(".unitToKeep").change(function() { t.selectUnitToKeep($(this)); });
	};
	
	this.selectUnitToInclude = function(input) {
		var mode = input.attr('checked');
		var name = input.attr("name");
		getCurrentOP().unitsToInclude[name] = mode=='checked';
		saveOPData();
	};
	
	this.selectUnitToKeep = function(input) {
		var amount = input.val();
		var name = input.attr("name");
		getCurrentOP().unitsToKeep[name] = amount;
		saveOPData();
	};
	
	this.useTab = function(input) {
		var tab = input.attr('checked');
		getCurrentOP().tabNukes = tab=='checked';
		saveOPData();
	};
	
	this.editScoutCount = function(input) {
		getCurrentOP().addScouts = input.val();
		saveOPData();
	};
	
	this.getUnitCounts = function() {
		var maxUnits = {};
		
		$.each(getCurrentOP().unitsToInclude, function(index, unit) {
			if(unit) {
				maxUnits[index] = Math.max(0, eval($("#unit_input_" + index).next().html()) - getCurrentOP().unitsToKeep[index]);
			}
		});
		
		maxUnits["spy"] = Math.min(getCurrentOP().addScouts, eval($("#unit_input_spy").next().html()));
		
		return maxUnits;
	};
	
	this.getTravelTime = function(maxUnits) {
		var target = "500|500"; //?
		var source = game_data.village.coord;

		target = target.split("|");
		source = source.split("|");
		var x = target[2] - source[2];
		var y = target[3] - source[3];
		
		var distance = Math.sqrt(x * x + y * y);
		var travelTime = 0;
		
		$.each(maxUnits, function(index, amount) {
			travelTime = Math.max(travelTime, Math.round(config.units[index].speed * 60 * distance * 1000));
		});
		
		return travelTime;
	};
	
	this.setUnits = function(rootElement, maxUnits) {
		var index = getCurrentOP().lastIndex;
		
		if(getCurrentOP().mode == 'random') {
			index = Math.floor(Math.random() * getCurrentOP().villages.length);
		}
		
		if(index < 0) {
			index = 0;
		}
		if(index >= getCurrentOP().villages.length) {
			getCurrentOP().lastIndex = 0;
			saveOPData();
			return "All villages done";
		}
		
		
		var target = getCurrentOP().villages[index];
		
		var spycount = maxUnits["spy"];
		var spyrequirement = getCurrentOP().units["spy"];
		if(spyrequirement == 'r' && spycount < getCurrentOP().unitcounts["spy"]) {
			return "The scout is required, but you ran out of them.";
		}
		
		var unitAdded = false;
		
		for(var i = config.units.list.length - 1; i >= 0; i--) {
			var unit = config.units.list[i];
			if(unit.id == "snob" || unit.id == "militia" || unit.id == "spy") {
				continue;
			}
			var count = maxUnits[unit.id];
			if(count == undefined) { count = 0; }
			var requirement = getCurrentOP().units[unit.id];
			if(requirement == undefined) { requirement = ""; }

			if(requirement != 'r' && (count < getCurrentOP().unitcounts[unit.id] || requirement != 'o')) {
				continue;
			}
			if(requirement == 'r' && count < getCurrentOP().unitcounts[unit.id]) {
				return "The unit " + unit.id + " is required, but you ran out of them.";
			}
			maxUnits[unit.id] -= getCurrentOP().unitcounts[unit.id];
			$('#unit_input_' + unit.id, rootElement).val(getCurrentOP().unitcounts[unit.id]);
			unitAdded = true;
		}
		if(spyrequirement == 'r' || spyrequirement == 'o' && spycount >= getCurrentOP().unitcounts["spy"]) {
			maxUnits["spy"] -= getCurrentOP().unitcounts["spy"];
			$("#unit_input_spy", rootElement).val(getCurrentOP().unitcounts["spy"]);
			unitAdded = true;
		}
		if(unitAdded) {
			var c = target.split("|");
			$("#units_form input[name=x]", rootElement).val(c[0]);
			$("#units_form input[name=y]", rootElement).val(c[1]);
			getCurrentOP().lastIndex = index + 1;
			saveOPData();
			return true;
		} else {
			return "No units where added.";
		}
	};
	
	this.openTabs = function(maxUnits) {
		var t = this;
		var opener = {originwindow:window, index:0, target:null, fakesMod:t, maxUnits:maxUnits, timer:-1};
		
		this.loadWindow(opener);
	};
	
	this.loadWindow = function(opener) {
		if(opener.index >= getCurrentOP().tabCount) {
			return;
		}
		opener.index++;
		
		opener.target = opener.originwindow.open(rallyLink,'_blank');
		opener.timer = setInterval(function(){
			//
			if(opener.target.document.readyState === "complete" && $("#units_form input[name=x]", opener.target.document.body).length > 0) {
				clearInterval(opener.timer);
				var res = opener.fakesMod.setUnits(opener.target.document.body, opener.maxUnits);
				if(res !== true) {
					$("#errorLine", opener.originwindow.document.body).toggle(true).append("Problem: " + res);
					return;
				}
				opener.fakesMod.loadWindow(opener);
			} else {
				//just wait
			}
		}, 300);
		opener.originwindow.focus();
	};
}

modules = {config:new ConfigModule(), fakes:new FakesModule(), nukes:new NukesModule()};





function saveOPData() {
	localStorage.setItem('twOPs', JSON.stringify(opData));
}

function main() {
	var opString = localStorage.getItem('twOPs');
	if(opString && opString.length > 0) {
		opData = JSON.parse(opString);
	} else {
		opData = {currentOP:null, opList:{}};
	}

	if($("#opplanner").length == 0) {
		$("#content_value").prepend($("<div>", {id:"opplanner"}));
	}

	var mod = modules[module];
	if(mod) {
		if(!mod.redirect()) {
			repaintModule();
		}
	} else {
		alert("The module " + module + " is not available.");
	}
}

function repaintModule() {
	var mod = modules[module];
	if(mod) {
		var rootPane = $("#opplanner");
		rootPane.empty();
		rootPane.append("<h2>OP Planner - " + module + "</h2>");
		mod.display(rootPane);
	}
}

function loadSettings() {
	config = new Config();
	config.onloaded = function() {
		main();
	};
	config.load();
}

function initSettings() {
	var configString = localStorage.getItem('twConfig');
	if(configString && configString.length > 0) {
		config = JSON.parse(configString);
	}
	if(config == null || !config.time || (new Date().getTime() - config.time) > 1000 * 3600 * 24 * 7) {
		$.getScript(scriptRoot+"settings.js", loadSettings);
	} else {
		main();
	}
}

initSettings();